package com.ncr.travel.appmgr.client.presenter;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.inject.Inject;
import com.ncr.nep.dashboardcore.rest.client.JSONCallback;
import com.ncr.travel.appmgr.client.ConfigurationItem;
import com.ncr.travel.appmgr.client.Constants;
import com.ncr.travel.appmgr.client.command.PostScreenConfigurationCommand;
import com.ncr.travel.appmgr.client.event.ConfigChangeEvent;
import com.ncr.travel.appmgr.client.event.ConfirmConfigChangeEvent;
import com.ncr.travel.appmgr.client.event.ConfirmConfigChangeEventHandler;
import com.ncr.travel.appmgr.client.event.PreviewConfigChangeEvent;
import com.ncr.travel.appmgr.client.event.PreviewConfigChangeEventHandler;
import com.ncr.travel.appmgr.client.event.UndoConfigChangeEvent;
import com.ncr.travel.appmgr.client.event.UndoConfigChangeEventHandler;
import com.ncr.travel.appmgr.client.model.ScreenConfigurationFactory;
import com.ncr.travel.appmgr.client.mvp.BasePresenter;
import com.ncr.travel.appmgr.client.mvp.EventBus;
import com.ncr.travel.appmgr.client.service.AppManagerWebService;
import com.ncr.travel.appmgr.client.view.FunctionView;
import com.ncr.travel.appmgr.model.shared.Function;
import com.ncr.travel.appmgr.model.shared.ScreenConfiguration;

public class FunctionPresenterImpl extends BasePresenter<FunctionView> implements FunctionPresenter {

	private final AppManagerWebService webService;
	private ScreenConfiguration screenConfiguration;
	
    /**
     * Factory for screen config model objects.
     */
	private ScreenConfigurationFactory screenConfigurationFactory;
	
	@Inject
	public FunctionPresenterImpl(AppManagerWebService webService, ScreenConfigurationFactory screenConfigurationFactory, EventBus eventBus, FunctionView functionView) {
		super(eventBus, functionView);
		System.out.println("Constructing FunctionPresenter");
		this.screenConfigurationFactory = screenConfigurationFactory;
		this.webService = webService;
		view.setPresenter(this);
		bind();
	}

	/**
	 * @see com.ncr.travel.appmgr.client.presenter.FunctionPresenter#setScreenConfiguration(com.ncr.travel.appmgr.model.shared.ScreenConfiguration)
	 */
	@Override
	public void setScreenConfiguration(final ScreenConfiguration screenConfiguration) {
		this.screenConfiguration = screenConfiguration;
		view.setScreenConfiguration(this.screenConfiguration);
	}

	@Override
	public void bind() {
		// TODO: S.O.P statements to be removed once testing is done
		System.out.println("(FunctionPresenter) Called bind()");
		registerHandler(eventBus.addHandler(ConfirmConfigChangeEvent.getType(), new ConfirmConfigChangeEventHandler() {
			public void onConfirm(ConfirmConfigChangeEvent event) {
				if (!ConfigurationItem.FUNCTION.equals(event.getConfigurationItem())) {
					// Dont process the event if the event is not generated by
					// functions widget
					return;
				}
				doConfirmConfigChanges(event.getFunctions());
			}
		}));
		registerHandler(eventBus.addHandler(UndoConfigChangeEvent.getType(), new UndoConfigChangeEventHandler() {
			public void onUndo(UndoConfigChangeEvent event) {
				if (!ConfigurationItem.FUNCTION.equals(event.getConfigurationItem())) {
					// Dont process the event if the event is not generated by
					// Text widget
					return;
				}
				doUndoConfigChanges();
			}
		}));
		registerHandler(eventBus.addHandler(PreviewConfigChangeEvent.getType(), new PreviewConfigChangeEventHandler() {
			public void onPreview(PreviewConfigChangeEvent event) {
				if (!ConfigurationItem.FUNCTION.equals(event.getConfigurationItem())) {
					// Dont process the event if the event is not generated by
					// functions widget
					return;
				}
				doPreviewConfigChanges();
			}
		}));
	}

	private void doConfirmConfigChanges(List<Function> funcList) {
//		final ScreenConfigurationJson screenConfig = new ScreenConfigurationJson(screenConfiguration);
		final ScreenConfiguration screenConfig = screenConfigurationFactory.screenConfiguration().as();
		screenConfig.setFunctions(funcList);

		new PostScreenConfigurationCommand(screenConfig, webService, new JSONCallback<ScreenConfiguration>(screenConfigurationFactory, ScreenConfiguration.class, Constants.MOCK_SERVER_MODE) {
			@Override
			public void onSuccess(ScreenConfiguration screenConfig) {
				eventBus.fireEvent(new ConfigChangeEvent(screenConfig));
			}

			@Override
			public void onFailure(Throwable throwable, int statusCode) {
				// TODO Auto-generated method stub
				
			}
		}).execute();
	}

	private void doPreviewConfigChanges() {
		System.out.println("Function preview config change event received");
	}

	private void doUndoConfigChanges() {
		System.out.println("Function undo config change event received");
	}

	@Override
	public void go(HasWidgets container) {
		System.out.println("(FunctionPresenter) Called go()");
		container.clear();
		container.add(view.asWidget());
		GWT.runAsync(new RunAsyncCallback() {
			public void onFailure(Throwable caught) {
				Window.alert("Code download failed");
			}

			public void onSuccess() {
				view.showView();
			}
		});
	}

}
